<?php
error_reporting(E_ALL);
@header('content-type: text/html; charset=utf-8');
class package{
	private $cur = array(
		'bs' => '', 				// 根目录
		'ds' => '', 				// 目录分隔符
		'root' => '', 				// 选定目录
		'folder' => '', 			// 选定文件夹
		'setting' => array(), 		// 选定设置
		'navigator' => array(),		// 支持菜单
		'fullpath' => '',			// 选定后的完整路径
		'compresstime' => '',		// 发布时间
	);
	private $conf = array(
		'mui' => array(
			'css' => array(
				'name' => '样式', 'type' => array('css'), 'saveas' => 'css', 'save' => array(
					'mui/demo/theme/css/mui.css',
					'../document/theme/mui.css'
				), 'copyright' => "/*!\n* Mobile UI CSS\n* @update: {COMPRESSTIME}\n*/"
			), 'js' => array(
				'name' => '脚本', 'type' => array('js'), 'saveas' => 'js', 'save' => array(
					'mui/demo/theme/js/mui.js',
					'../document/theme/mui.js'
				), 'copyright' => "/*!\n* Mobile UI JS\n* @update: {COMPRESSTIME}\n*/"
			)
		), 
		'pui' => array(
			'css' => array(
				'name' => '样式', 'type' => array('css'), 'saveas' => 'css', 'save' => array(
					'../document/theme/pui.css'
				), 'copyright' => "/*!\n* Computer UI CSS\n* @update: {COMPRESSTIME}\n*/"
			), 'js' => array(
				'name' => '脚本', 'type' => array('js'), 'saveas' => 'js', 'save' => array(
					'../document/theme/pui.js'
				), 'copyright' => "/*!\n* Computer UI JS\n* @update: {COMPRESSTIME}\n*/"
			)
		)
	);
	public function __construct(){
		/*!
		 * 环境变量
		 */
		isset($_GET) && is_array($_GET) || $_GET = array();
		isset($_GET['r']) || $_GET['r'] = '';
		isset($_GET['f']) || $_GET['f'] = '';
		isset($_POST) && is_array($_POST) || $_POST = array();
		isset($_SERVER) && is_array($_SERVER) || $_SERVER = array();
		/*!
		 * 低层目录与目录分隔符
		 */
		$this->cur['bs'] = dirname(__FILE__);
		$this->cur['ds'] = DIRECTORY_SEPARATOR;;
		$this->cur['COMPRESSTIME'] = date('r');
		/*!
		 * 按配置分析
		 */
		$ri = 0; foreach ($this->conf as $ck => $cv){
			$this->cur['navigator'][] = array('nm' => $ck, 'nv' => $cv); $ri++; if ($ri == 1 || $ck == $_GET['r']){
				$fi = 0; $this->cur['root'] = $ck; foreach ($cv as $vk => $vv){
					$fi++; if ($fi == 1 || $vk == $_GET['f']){
						$this->cur['folder'] = $vk;
						$this->cur['setting'] = $vv;
					}
				}
			}
		}
		/*!
		 * 算完整路径
		 */
		$this->cur['fullpath']  = $this->cur['bs'].$this->cur['ds'];
		$this->cur['fullpath'] .= $this->cur['root'].$this->cur['ds'];
		$this->cur['fullpath'] .= $this->cur['folder'];
		/**
		 * 操作文件夹
		 */
		$this->_folder();
	}
	private function _folder(){
		/**
		 * 读取当前目录下全部文件
		 */
		$_directory = $this->_directory(); 
		/*!
		 * 保存压缩文件
		 */
		if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST'){
			return $this->_saveas($_directory);
		}
		/*!
		 * 文件列表
		 */
		$html  = '<html>';
		$html .= '<head>';
			$html .= '<meta charset="utf-8">';
			$html .= '<title>'.$this->cur['setting']['name'].'</title>';
			$html .= '<style>*{margin:0;padding:0;vertical-align:middle;font-weight:normal;font-style:normal;}body{padding:15px;background-color:#f3f3f3;}li{list-style:none;}';
			$html .= 'h1{padding:35px 0;font-size:30px;}';
			$html .= 'h1 small{font-size:14px;}';
			$html .= 'ul{padding:25px;border:1px solid #999;background-color:#ddd;border-radius:3px;}';
			$html .= 'ul li em {color:#999;font-size:12px;}';
			$html .= 'button{margin:10px 0 0 0;padding:0 15px;height:35px;line-height:35px;border:1px solid #999;border-radius:3px;}';
			$html .= '</style>';
		$html .= '</head>';
		$html .= '<body>';
			$html .= '<header>'; foreach ($this->cur['navigator'] as $nak => $nav){
				$html .= $nav['nm'].'('; foreach ($nav['nv'] as $snk => $snv){
				$html .= ' <a href="?r='.$nav['nm'].'&amp;f='.$snk.'"> '.$snv['name'].'</a>'; }
				$html .= ')';}
			$html .= '</header>'; 
			$html .= '<h1>文件列表 <small>('.count($_directory).')</small></h1>';
			$html .= '<form action="?r='.$this->cur['root'].'&amp;f='.$this->cur['folder'].'" method="post">';
			$html .= '<ul>'; $_checked = isset($_GET['none']) && $_GET['none'] ? '' : ' checked'; foreach ($_directory as $_file){
				$html .= '<li><input type="checkbox" name="sels[]" value="'.$_file['hash'].'"'.$_checked.' />'.$_file['path'].' <em>( '.$_file['size'].' Kb )</em></li>'; }
			$html .= '</ul>';
			$html .= '<div><button>合并并压缩</button> <a href="?r='.$this->cur['root'].'&amp;f='.$this->cur['folder'].'">ALL</a> | <a href="?r='.$this->cur['root'].'&amp;f='.$this->cur['folder'].'&amp;none=1">NULL</a></div>';
			$html .= '</form>';
		$html .= '</body>';
		$html .= '</html>';
		print $html; exit;
	}
	private function _directory($r = array(), $z = ''){
		$d  = $this->cur['fullpath']; $z && $d .= $this->cur['ds'].$z; if (is_dir($d)){
			$f = dir($d); while (false !== ($file = $f->read())){
				$p = $d.$this->cur['ds'].$file; 
				/**
				 * 加入列表
				 */
				if (is_file($p)){
					if (!preg_match("/\.(dev|bak)\./i", $p)){
						if (preg_match("/\.([_a-z0-9]+)$/i", $p, $m)){
							$hash = md5(strtoupper($p)); in_array($m[1], $this->cur['setting']['type']) && $r[$hash] = array(
								'name' => $file,
								'path' => $p, 
								'size' => round(filesize($p) / 1024, 2), 
								'hash' => md5(strtoupper($p))
							);
						}
					}
				}
				/**
				 * 目录递归
				 */
				else if (is_dir($p) && !preg_match("/^([\.]+)$/", $file)){
					$z && $file = $z.$this->cur['ds'].$file;
					$r = $this->_directory($r, $file);
				}
			} $f->close();
		} return $r;
	}

	private $_saveas_buffer = '';
	private $_saveas_sized = 0;
	private function _saveas(& $f){
		$this->_saveas_buffer = ''; isset($_POST['sels']) && is_array($_POST['sels']) || $_POST['sels'] = array(); foreach ($f as $k => $a){
			in_array($k, $_POST['sels']) && $this->_saveas_open($a);
		}
		/*!
		* 压缩
		*/
		switch ($this->cur['setting']['saveas']){			
			case 'css' : $this->_saveas_buffer = $this->_saveas_compress_css($this->_saveas_buffer); break;
			case 'js' : $this->_saveas_buffer = $this->_saveas_compress_js($this->_saveas_buffer); break;
		}
		
		
		// $this->_saveas_buffer = gzcompress($this->_saveas_buffer, 1);
		
		/*!
		 * 更新时间
		 */
		$this->cur['setting']['copyright'] = preg_replace(
			"/\{COMPRESSTIME\}/", 
			$this->cur['COMPRESSTIME'], 
			$this->cur['setting']['copyright']
		); $this->_saveas_buffer = $this->cur['setting']['copyright']."\n".$this->_saveas_buffer;
		
		
		
		/*!
		 * 文件列表
		 */
		$html  = '<html>';
		$html .= '<head>';
			$html .= '<meta charset="utf-8">';
			$html .= '<title>'.$this->cur['setting']['name'].'</title>';
			$html .= '<style>*{margin:0;padding:0;vertical-align:middle;font-weight:normal;font-style:normal;}body{padding:15px;background-color:#f3f3f3;}li{list-style:none;}';
			$html .= 'h1{padding:35px 0;font-size:30px;}';
			$html .= 'h1 small{font-size:14px;}';
			$html .= 'ul{padding:25px;border:1px solid #999;background-color:#ddd;border-radius:3px;}';
			$html .= 'ul li em {color:#999;font-size:12px;}';
			$html .= 'button{margin:10px 0 0 0;padding:0 15px;height:35px;line-height:35px;border:1px solid #999;border-radius:3px;}';
			$html .= '</style>';
		$html .= '</head>';
		$html .= '<body>';
			$html .= '<header>'; foreach ($this->cur['navigator'] as $nak => $nav){
				$html .= $nav['nm'].'('; foreach ($nav['nv'] as $snk => $snv){
				$html .= ' <a href="?r='.$nav['nm'].'&amp;f='.$snk.'"> '.$snv['name'].'</a>'; }
				$html .= ')';}
			$html .= '</header>'; 
			$html .= '<h1>已合并并缩到以下位置</h1>';
			$html .= '<ul>'; $i = 0; foreach ($this->cur['setting']['save'] as $s){$i++; if ($fp = @fopen($s, 'wb+')){fwrite($fp, $this->_saveas_buffer);fclose($fp); $size = filesize($s);
				$html .= '<li>['.sprintf('%02d', $i).'] '.$s.' <em>( '.round($size/1024, 2).' Kb, '.round(($size/$this->_saveas_sized) * 100, 2).'% )</em></li>';}}
			$html .= '</ul>';
		$html .= '</body>';
		$html .= '</html>';
		print $html; exit;
	}
	private function _saveas_open($a){
		$buffer = ''; if (is_array($a) && isset($a['path']) && file_exists($a['path'])){
			if ($fp = @fopen($a['path'], 'r')){
				$size = filesize($a['path']); $this->_saveas_sized += $size;
				$buffer = fread($fp, $size);
				fclose($fp);
			}
		} $buffer && $this->_saveas_buffer .= "\n".$buffer;
	}
	private function _saveas_compress_css($s){
		return preg_replace(array(
			"/\/\*(.+?)\*\//s", "/\/\/(.+?)/", 					// #1: 注释
			"/\t|\r|\n/", 										// #2: 换行、回车、制表符
			"/\s+(\{|:|,|;)/",									// #3: 前空格
			"/(\{|:|,|;)\s+/",									// #4: 后空格
		), array(
			"", "", 											// #1: 去除
			"",													// #2: 去除
			"\\1", 												// #3: 过滤
			"\\1" 												// #4: 过滤
		), $s);
	}
	private function _saveas_compress_js($s){
		// return $s;
		return preg_replace(array(
			"/\/\*(.+?)\*\//s", 
			"/\/\/(.+?)\n$/", 					// #1: 注释
			"/\t|\r|\n/", 										// #2: 换行、回车、制表符
			"/\s+(\+\-\[\]\{|\}|\(|\)|\|\||\?|=|:|,|;)/",		// #3: 前空格"{([])}||?+-|,;"
			"/(\+\-\[\]\{|\}|\(|\)|\|\||\?|=|:|,|;)\s+/"		// #4: 后空格"{([])}||?+-|,;"
		), array(
			"", "", 											// #1: 去除
			"",													// #2: 去除
			"\\1",
			"\\1"
		), $s);
	}
} new package();